/*
 * Copyright  2018 Linkel Technology Co., Ltd, Beijing
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BA SIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 */
import React, { Component } from 'react';
import { connect } from 'react-redux';
import { SaveButton, DeleteButton, Toolbar, crudUpdate } from 'react-admin';
import { Crypto } from 'rclink';
import cloneDeep from 'lodash/cloneDeep';
import { showNotification } from 'react-admin';
import { Link } from "react-router-dom";
import Button from '@material-ui/core/Button';
import Icon from '@material-ui/core/Icon';
import withStyles from "@material-ui/core/styles/withStyles";
import { GraphQLClient } from "graphql-request";
import settings from "../../settings";
import LinearProgress from "@material-ui/core/LinearProgress";

const saveToUpdate = (data, previousData, basePath, redirectTo) => {
    return crudUpdate('keypairs', data.id, data, previousData, basePath, redirectTo);
}

class SaveWithAdjustmentButtonView extends Component {
    handleClick = () => {
        const { basePath, handleSubmit, redirect, saveToUpdate, showNotification } = this.props;

        return handleSubmit(values => {
            let data = cloneDeep(values);
            let previousData = cloneDeep(values);
            if (data.kp.pwdOld) {
                try {
                    data.kp.prvKeyPEM = Crypto.GetKeyPEM(Crypto.ImportKey(data.kp.prvKeyPEM, data.kp.pwdOld), data.kp.pwd1);
                    delete data.kp.pwdOld;
                    delete data.kp.pwd1;
                    delete data.kp.pwd2;

                    delete previousData.kp.pwdOld;
                    delete previousData.kp.pwd1;
                    delete previousData.kp.pwd2;
                }
                catch (e) {
                    console.error(e);
                    if (e.message === '提供的私钥信息无效或解密密码无效')
                        showNotification('您输入的旧密码错误', 'warning');
                    else
                        showNotification(e.message, 'warning');
                    return;
                }
            }
            return saveToUpdate(data, previousData, basePath, redirect);
        });
    };

    render() {
        const { handleSubmitWithRedirect, ...props } = this.props;

        return (
            <SaveButton
                handleSubmitWithRedirect={this.handleClick}
                {...props}
            />
        );
    }
}

const SaveWithAdjustmentButton = connect(
    undefined,
    {
        saveToUpdate,
        showNotification
    }
)(SaveWithAdjustmentButtonView);

const styles = (theme) => ({
    toolbar: {
        justifyContent: "space-between"
    },
    myButton: {
        marginLeft: 30,
        minHeight: 36,
    },
    myButtonIcon: {
        marginRight: 8,
    },
});

const graphqlClient = new GraphQLClient(`${settings.Prisma.endpoint}`);
const DELIMITER = "#";

class EditToolbar extends Component {
    constructor(props) {
        super(props);
        this.state = {
            registrationstatus: null,
        };
    }

    componentDidMount() {
        const { ownerCreditCode, name } = this.props.record;
        const creditCodeCombineName = `${ownerCreditCode}${DELIMITER}${name}`;
        graphqlClient.request(`
            {
               cert(where: {
                   creditCodeCombineName: "${creditCodeCombineName}"
               }){
                   id
               }
            }
        `).then((res) => {
            if (res.cert) this.setState({ registrationstatus: true });
            else this.setState({ registrationstatus: false });
        });
    }

    render() {
        const { name, ownerCreditCode } = this.props.record;
        const { certStatus } = this.props;
        const { sigAlg } = this.props.record.cert;
        let { certPEM } = this.props.record.cert;
        const regTime = Date.now();
        const seconds = parseInt(regTime / 1000, 10);
        const nanos = (regTime % 1000) * 1000000;
        certPEM = certPEM.replace(/\r\n/g, "\\r\\n"); // for windows new line characters
        certPEM = certPEM.replace(/\n/g, "\\n"); // for unix/linux new line characters
        const { classes } = this.props;
        const { registrationstatus } = this.state;
        return (
            <Toolbar {...this.props} className={classes.toolbar} >
                <div>
                    <SaveWithAdjustmentButton
                        redirect="show"
                        submitOnEnter={false}
                        variant="raised"
                        {...this.props}
                    />
                    {
                        registrationstatus === null
                            ? <LinearProgress />
                            : (
                                registrationstatus
                                    ? null
                                    : <Button
                                        variant="contained"
                                        color="primary"
                                        className={classes.myButton}
                                        id="registerCert"
                                        component={Link}
                                        to={{
                                            pathname: "/Transaction/create",
                                            state: {
                                                chaincodeName: "ContractCert",
                                                chaincodeVersion: 1,
                                                chaincodeFunction: "SignUpCert",
                                                chaincodeArgs: [`{"name":"${name}", "credit_code":"${ownerCreditCode}", "cert":{ "certificate":"${certPEM}", "algType":"${sigAlg}", "certValid":${certStatus},"regTime":{ "seconds":${seconds},"nanos":${nanos} } } }`],
                                            },
                                        }}
                                    >
                                        <Icon className={classes.myButtonIcon}>note_add</Icon>
                                        注册证书
                                </Button>
                            )
                    }
                    {
                        registrationstatus === null
                            ? <LinearProgress />
                            : (
                                registrationstatus
                                    ? <Button
                                        variant="contained"
                                        color="primary"
                                        className={classes.myButton}
                                        component={Link}
                                        to={{
                                            pathname: "/Transaction/create",
                                            state: {
                                                chaincodeName: "ContractCert",
                                                chaincodeVersion: 1,
                                                chaincodeFunction: "UpdateCertStatus",
                                                chaincodeArgs: [`{"name":"${name}", "credit_code":"${ownerCreditCode}", "status":${certStatus} }`],
                                            },
                                        }}
                                    >
                                        <Icon className={classes.myButtonIcon}>edit</Icon>
                                        更新证书状态
                                    </Button>
                                    : null
                            )
                    }
                </div>
                <DeleteButton
                    redirect="/keypairs"
                    resource='keypairs'
                    record={this.props.record}
                />
            </Toolbar>
        )
    }
};

export default withStyles(styles)(EditToolbar);